Py.Cafe

banana0000/

Dallas Animal Shelter

Dallas Animal Shelter

DocsPricing
  • assets/
  • .emptyFolderPlaceholder
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import dash
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
from dash import dcc, html
import plotly.express as px
import pandas as pd

# Load Data
df = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-8/Dallas_Animal_Shelter_Data_Fiscal_Year_Jan_2024.csv")
df["Intake_Time"] = pd.to_datetime(df["Intake_Time"]).dt.hour
df["Intake_Date"] = pd.to_datetime(df['Intake_Date'])
df["Outcome_Date"] = pd.to_datetime(df['Outcome_Date'])
df["Animal_Stay_Days"] = (df["Outcome_Date"] - df["Intake_Date"]).dt.days

# Initialize Dash app with Bootstrap theme
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.SKETCHY])

# Custom color palette (teal/blue-green tones)
custom_colors = ["#17becf", "#1f77b4", "#2ca02c", "#ff7f0e", "#d62728"]

# Layout with KPIs
app.layout = dbc.Container([ 
    dbc.Row([dbc.Col(html.H1("Analytics Dashboard of Dallas Animal Shelter", className="text-center text-light"), width=12)], 
            className="my-2 bg-primary p-2"), 
    dbc.Row([dbc.Col(html.Br(), width=12)]),  

    # KPI Cards Row
    dbc.Row([ 
        dbc.Col(dbc.Card(
            dbc.CardBody([ 
                html.H4("Total Animals", className="card-title"), 
                html.H5(id="total-animals", className="card-text", style={"color": "black"})
            ]), 
            color="white", outline=True, style={"border-radius": "15px"}
        ), width=4),
        dbc.Col(dbc.Card(
            dbc.CardBody([ 
                html.H4("Average Stay Duration", className="card-title"), 
                html.H5(id="avg-stay", className="card-text", style={"color": "black"})
            ]), 
            color="white", outline=True, style={"border-radius": "15px"}
        ), width=4),
        dbc.Col(dbc.Card(
            dbc.CardBody([ 
                html.H4("Unique Breeds", className="card-title"), 
                html.H5(id="unique-breeds", className="card-text", style={"color": "black"})
            ]), 
            color="white", outline=True, style={"border-radius": "15px"}
        ), width=4)
    ], className="mb-4"),

    # Dropdown for animal type filter
    dbc.Row([ 
        dbc.Col(dcc.Dropdown(
            id='animal-type', 
            clearable=False,
            value="ALL",  
            options=[{'label': x, 'value': x} for x in ['ALL'] + df["Animal_Type"].unique().tolist()],
            className="animal-type-dropdown", style={"border-radius": "15px"}
        ), width=4)
    ], className="mb-4"),

    # Graphs in 2 columns
    dbc.Row([ 
        dbc.Col(html.Div(dcc.Graph(id='histogram', style={"border-radius": "15px", "overflow": "hidden"})), width=6),
        dbc.Col(html.Div(dcc.Graph(id='ecdf', style={"border-radius": "15px", "overflow": "hidden"})), width=6)
    ]),

    html.Br(),

    # Graphs in 3 columns
    dbc.Row([ 
        dbc.Col(html.Div(dcc.Graph(id='pie', style={"border-radius": "15px", "overflow": "hidden"})), width=4),  
        dbc.Col(html.Div(dcc.Graph(id='strip-chart', style={"border-radius": "15px", "overflow": "hidden"})), width=4),
        dbc.Col(html.Div(dcc.Graph(id='sunburst', style={"border-radius": "15px", "overflow": "hidden"})), width=4)
    ])
], fluid=True, style={"max-width": "1400px", "margin": "auto"})  

# Callbacks for updating graphs and KPIs
@app.callback(
    [Output("pie", "figure"), 
     Output("strip-chart", "figure"),
     Output("sunburst", "figure"),
     Output("ecdf", "figure"),
     Output("histogram", "figure"),
     Output("total-animals", "children"),
     Output("avg-stay", "children"),
     Output("unique-breeds", "children")],
    [Input("animal-type", "value")]
)
def update_graphs_and_kpis(animal_chosen):
    if animal_chosen != 'ALL':
        df_filtered = df[df["Animal_Type"] == animal_chosen]
    else:
        df_filtered = df

    # Update KPIs
    total_animals = f"{df_filtered.shape[0]:,}"
    avg_stay = f"{df_filtered['Animal_Stay_Days'].mean():.2f} days"
    unique_breeds = f"{df_filtered['Animal_Breed'].nunique():,}"

    # Histogram (single color)
    fig_hist = px.histogram(df_filtered, 
                             x="Animal_Breed", 
                             title="Animal Count by Breed", 
                             color="Animal_Breed", 
                             color_discrete_sequence=["#17becf"],  # Single color for the histogram
                             category_orders={"Animal_Breed": df_filtered["Animal_Breed"].unique().tolist()})
    fig_hist.update_layout(plot_bgcolor='white', paper_bgcolor='white', showlegend=False)

    # Pie chart
    fig_pie = px.pie(df_filtered, names="Animal_Type", title="Animal Type", hole=0.6, 
                     color_discrete_sequence=custom_colors)
    fig_pie.update_layout(plot_bgcolor='white', paper_bgcolor='white', showlegend=True)

    # Strip chart
    fig_strip = px.strip(df_filtered, x="Animal_Stay_Days", y="Intake_Type", title="Stay Duration by Intake Type", 
                         color_discrete_sequence=["#17becf"])
    fig_strip.update_layout(plot_bgcolor='white', paper_bgcolor='white', showlegend=False)

    # Sunburst chart
    fig_sunburst = px.sunburst(df_filtered.dropna(subset=['Chip_Status']), path=["Animal_Type", "Intake_Type", "Chip_Status"], 
                               title="Animal Intake and Chip Status", 
                               color_discrete_sequence=custom_colors)
    fig_sunburst.update_layout(plot_bgcolor='white', paper_bgcolor='white', showlegend=False)

    # ECDF chart
    fig_ecdf = px.ecdf(df_filtered, x="Animal_Stay_Days", color="Animal_Type", title="ECDF of Animal Stay Days",
                       color_discrete_sequence=custom_colors)
    fig_ecdf.update_layout(plot_bgcolor='white', paper_bgcolor='white', showlegend=True)
    fig_ecdf.update_traces(line=dict(width=3))

    return fig_pie, fig_strip, fig_sunburst, fig_ecdf, fig_hist, total_animals, avg_stay, unique_breeds

if __name__ == '__main__':
    app.run_server(debug=True)